
class LatexReader:
    def __init__(self, max_tokens) -> None:
        self.max_tokens = max_tokens
    
    def process_latex_file(self, input_file, latex_process_processor):  
        symbols = ["\\chapter", "\\section", "\\subsection", "\\subsubsection"]
        blocks = self._read_latex_blocks(input_file, symbols,self.max_tokens)
        latex_process_processor.process(blocks)

    def _read_latex_blocks(self, input_file, symbols=["\\chapter", "\\section", "\\subsection", "\\subsubsection"], max_length=4000):
        chunks = self._read_latex_chunks(input_file, symbols)
        block = ""
        for chunk in chunks:
            if len(block + chunk) > max_length:
                yield block
                block = ""
            block += chunk
        if block:
            yield block
        
    def _read_latex_chunks(self, input_file, symbols=["\\chapter", "\\section", "\\subsection", "\\subsubsection"]):
        """
        read latex file and split it into chunks
        based on the symbols
        if there is a lstlisting environment,
        the lstlisting environment will be replaced by a placeholder
        """
        with open(input_file, "r") as file:
            global code_blocks
            code_blocks = []
            in_lstlisting = False
            lines = file.readlines()
            chunk = []
            for line in lines:
                if line.strip().startswith(tuple(symbols)):
                    if chunk:
                        yield "".join(chunk)
                        chunk = []
                elif '\\begin{lstlisting}' in line:
                    code_blocks.append(line)
                    in_lstlisting = True
                    continue
                elif '\\end{lstlisting}' in line:
                    code_blocks[-1] += line
                    chunk.append(f'%%{{{len(code_blocks) - 1}}}%%')
                    in_lstlisting = False
                    continue
                elif in_lstlisting:
                    code_blocks[-1] += line
                else:
                    chunk.append(line)
                
            if chunk:
                yield "".join(chunk)


class BaseLatexBlockProcessor:
    def __init__(self) -> None:
        pass
    def process(self):
        raise NotImplementedError("Subclass must implemented this method")                